package com.niuniu.rushdorm.filter;

import com.niuniu.rushdorm.exception.ReportedException;
import com.niuniu.rushdorm.mapper.SysMapper;
import com.niuniu.rushdorm.pojo.vo.UserVO;
import com.niuniu.rushdorm.util.JwtUtils;
import com.niuniu.rushdorm.util.StatusEnum;
import io.jsonwebtoken.Claims;
import io.jsonwebtoken.security.SignatureException;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Component;
import org.springframework.util.StringUtils;
import org.springframework.web.filter.OncePerRequestFilter;

import javax.servlet.FilterChain;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.util.HashSet;
import java.util.Set;

/**
 * @author Meng
 * 2022/11/22
 */
@Slf4j
@Component
public class AuthFilter extends OncePerRequestFilter {
    @Autowired
    RedisTemplate redisTemplate;
    @Autowired
    SysMapper sysMapper;

    private Long startTime;
    private Long endTime;
    private Integer classLimit;

    @Override
    protected void initFilterBean() throws ServletException {
        super.initFilterBean();
        startTime = Long.valueOf(sysMapper.getConfigValue("start_time"));
        endTime = Long.valueOf(sysMapper.getConfigValue("end_time"));
        classLimit = Integer.valueOf(sysMapper.getConfigValue("class_limit"));
    }
    @Override
    protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain) throws ServletException, IOException {
        Long now = System.currentTimeMillis()/1000;
        if(now < startTime){
            throw ReportedException.build(StatusEnum.NOT_START);
        }
        if(now > endTime){
            throw ReportedException.build(StatusEnum.END);
        }
        String authString = request.getHeader("Authorization");
        if(!StringUtils.hasText(authString)||!authString.startsWith("Bearer ")){
            throw ReportedException.build(StatusEnum.UNLOGIN);
        }
        String jws = authString.substring(7).replaceAll(" ","");
        try {
            Claims claims = JwtUtils.getClaims(jws);
            String token_id = claims.get("token_id",String.class);
            Long uid = claims.get("uid",Long.class);
            String cache_id = (String)redisTemplate.opsForValue().get("access_token:"+String.valueOf(uid));
            if(cache_id==null||!cache_id.equals(token_id)){
                throw ReportedException.build(StatusEnum.UNVALID_TOKEN);
            }
            UserVO userVO = JwtUtils.getUserVO(jws);
            request.setAttribute("userVO",userVO);
            request.setAttribute("uid",userVO.getUid());
            request.setAttribute("class_limit",classLimit);
        }catch (SignatureException e){
            throw ReportedException.build(StatusEnum.ILLEGAL_TOKEN);
        }
        filterChain.doFilter(request,response);
    }
}
